﻿
using System;
using System.Text;
using CatEars.Core.Numbers;

namespace CatEars.Text
{
    /// <summary>
    /// 字符串显示相关
    /// </summary>
    public static class Display
    {
        #region object display

        /// <summary>
        /// 将object转为字符串
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static string ObjectDisplay(object obj)
        {
            if (obj == null)
            {
                return "<null>";
            }
            else if (obj is DBNull)
            {
                return "<DBNull>";
            }
            else
            {
                return obj.ToString();
            }
        }

        #endregion

        #region Number Display

        /// <summary>
        /// 将数值显示为合适的单位
        /// </summary>
        /// <param name="dblValue">数值</param>
        /// <param name="conv">转换器</param>
        /// <param name="strInputUnit">当前单位</param>
        /// <param name="strOutputUnit">输出单位（若不指定则按dblMin dblMax自动计算一个合适的值）</param>
        /// <param name="dblMin">若不指定strOutputUnit则按dblMin和dblMax自动计算一个合适的值 下限</param>
        /// <param name="dblMax">若不指定strOutputUnit则按dblMin和dblMax自动计算一个合适的值 上限</param>
        /// <returns>处理后的字符串</returns>
        public static string DisplayNumber(double dblValue,
            UnitConv conv,
            string strInputUnit,
            string strOutputUnit = null,
            double dblMin = 1,
            double dblMax = 1000)
        {
            double dblNewValue;
            if (!string.IsNullOrEmpty(strOutputUnit))
            {
                dblNewValue = conv.Convert(dblValue, strInputUnit, strOutputUnit);
            }
            else
            {
                dblNewValue = dblValue;
                int intCurrentUnitIndex = conv.GetUnitIndex(strInputUnit);
                int intFinialUnit = intCurrentUnitIndex;
                if (dblValue < dblMin)
                {
                    //太小，把数字转大
                    double dblNewValueTmp = dblValue;
                    while (intFinialUnit > 0)
                    {
                        --intFinialUnit;
                        double dblNewValue0 = conv.Convert(dblValue, intCurrentUnitIndex, intFinialUnit);
                        if (dblNewValue0 > dblMax)
                        {
                            dblNewValue = dblNewValueTmp;
                            ++intFinialUnit;
                            break;
                        }
                        if (dblNewValue0 >= dblMin)
                        {
                            dblNewValue = dblNewValue0;
                            break;
                        }
                        dblNewValueTmp = dblNewValue0;
                    }
                    if (dblNewValue < dblMin)
                    {
                        dblNewValue = dblNewValueTmp;
                    }
                }
                else
                {
                    //太大，把数字转小
                    double dblNewValueTmp = dblValue;
                    while (intFinialUnit < conv.PowerArr.Length - 1)
                    {
                        ++intFinialUnit;
                        double dblNewValue0 = conv.Convert(dblValue, intCurrentUnitIndex, intFinialUnit);
                        if (dblNewValue0 < dblMin)
                        {
                            dblNewValue = dblNewValueTmp;
                            --intFinialUnit;
                            break;
                        }
                        //if (dblNewValue0 < dblMax && dblNewValue0 >= dblMin)
                        //{
                        //    dblNewValue = dblNewValue0;
                        //    break;
                        //}
                        dblNewValueTmp = dblNewValue0;
                    }
                    if (dblNewValue > dblNewValueTmp)
                    {
                        dblNewValue = dblNewValueTmp;
                    }
                }
                strOutputUnit = conv.NameArr[intFinialUnit];
            }
            return string.Format("{0:0.##}{1}", dblNewValue, strOutputUnit);
        }

        #region Byte Display
        /// <summary>
        /// Byte转中文显示（进制为1000）
        /// </summary>
        /// <param name="lngLength">文件大小 单位B</param>
        /// <param name="strUnit">输出单位（若不指定则自动计算一个合适的值）</param>
        /// <returns>处理后的字符串</returns>
        public static string ByteToString0(long lngLength, string strUnit = null)
        {
            return DisplayNumber(lngLength, UnitConv.ConvByte0.Instance, "B", strUnit, 0.5, 500);
        }
        /// <summary>
        /// Byte转中文显示（进制为1024）
        /// </summary>
        /// <param name="lngLength">文件大小 单位B</param>
        /// <param name="strUnit">输出单位（若不指定则自动计算一个合适的值）</param>
        /// <returns>处理后的字符串</returns>
        public static string ByteToString(long lngLength, string strUnit = null)
        {
            return DisplayNumber(lngLength, UnitConv.ConvByte.Instance, "B", strUnit, 0.5, 500);
        }
        #endregion

        #endregion

        #region DateTimeDisplay

        /// <summary>
        /// 显示时间
        /// </summary>
        /// <param name="ts"></param>
        /// <returns></returns>
        public static string DisplayTime(TimeSpan ts)
        {
            StringBuilder strB = new StringBuilder();
            if (ts.Days != 0)
            {
                strB.Append(ts.Days);
                strB.Append("天");
            }
            if (ts.Hours != 0)
            {
                strB.Append(ts.Hours);
                strB.Append("时");
            }
            if (ts.Minutes != 0)
            {
                strB.Append(ts.Minutes);
                strB.Append("分");
            }
            if (strB.Length == 0)
            {
                if (ts.Seconds > 10)
                {
                    strB.Append(ts.Seconds);
                    strB.Append("秒");
                }
                else
                {
                    strB.AppendFormat("{0:N3}秒", ts.TotalSeconds);
                }
            }
            return strB.ToString();
        }

        #endregion
    }
}
